
package com.feib.soeasy.dao.hibernate;

import java.util.ArrayList;
import java.util.Date;

import org.hibernate.Query;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Example;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Repository;

import com.feib.soeasy.dao.PaymentCanceledDao;
import com.feib.soeasy.model.Group;
import com.feib.soeasy.model.Payment;
import com.feib.soeasy.model.PaymentCanceled;
import com.feib.soeasy.model.User;
import com.feib.soeasy.pagination.PaginatedList;
import com.feib.soeasy.util.UserUtil;


/**
 * @title (#)PaymentCanceledHibernateDao.java<br>
 * @description <br>
 * @author Jimmy Liu<br>
 * @version 1.0.0 2010/11/25
 * @copyright Far Eastern International Bank Copyright (c) 2010<br>
 * @2010/12/1 create by Jimmy Liu<br>
 */
@Repository("paymentCanceledDao")
public class PaymentCanceledHibernateDao extends BaseHibernateDao<PaymentCanceled, Long> implements PaymentCanceledDao 
{
    @SuppressWarnings("unchecked")
    public PaginatedList<PaymentCanceled> queryUnConfirm(Payment payment, Group group, Date cancelDateFrom, Date cancelDateTo, PaginatedList<Payment> paginationConfig)
    {
        PaginatedList<PaymentCanceled> result = new PaginatedList<PaymentCanceled>();

        result.setPageSize(paginationConfig.getPageSize());
        result.setPageNumber(paginationConfig.getPageNumber());
        result.setSortCriterion(paginationConfig.getSortCriterion());
        result.setSortDirection(paginationConfig.getSortDirection());
        
        result.setFullListSize(super.countByDetachedCriteria(createUnConfirmDetachedCriteria(payment, group, cancelDateFrom, cancelDateTo)));


        // 筆數大於0
        if (0 < result.getFullListSize())
        {
            DetachedCriteria criteria = createUnConfirmDetachedCriteria(payment, group, cancelDateFrom, cancelDateTo);

            //排序
            if (null != paginationConfig.getSortCriterion())
            {
                // 由小到大
                if (PaginatedList.SORT_DIRECTION_ASC == paginationConfig.getSortDirection())
                {
                    criteria.addOrder(Order.asc(paginationConfig.getSortCriterion()));
                }
                else // 由大到小
                {
                    criteria.addOrder(Order.asc(paginationConfig.getSortCriterion()));
                }
            }


            int maxResults = result.getPageSize(); //the maximum number of results
            int firstResult = result.getFirstIndexForCurrentPage();  //the first result to retrieve, numbered from 0
            result.setPaginatedList(this.getHibernateTemplate().findByCriteria(criteria, firstResult, maxResults));
        }

        return result;
    }

    /**
     * @param payment 鎖定哪一個繳費單
     * @param group  放行人員所屬的帳單業者
     * @param cancelDateFrom 註銷日期起
     * @param cancelDateTo 註銷日期迄
     * @return
     */
    private DetachedCriteria createUnConfirmDetachedCriteria(Payment payment, Group group, Date cancelDateFrom, Date cancelDateTo) 
    {
        DetachedCriteria criteria = DetachedCriteria.forClass(this.getPersistentClass());
        criteria.setResultTransformer(DetachedCriteria.DISTINCT_ROOT_ENTITY);
        
        // 未作任何放行/不放行 動作
        criteria.add(Restrictions.isNull("confirmStatus"));
        
        // 屬於哪一帳單
        if (null != payment)
        {
            DetachedCriteria detachedCriteria = criteria.createCriteria("payment");

            // PK 有值，需加入為查詢條件
            if (null != payment.getPaymentPk())
            {
                detachedCriteria.add(Restrictions.idEq(payment.getPaymentPk()));
            }
            // Group 其他查詢條件
            Example e = Example.create(payment);
            e.enableLike(MatchMode.START);
            e.excludeZeroes();
            detachedCriteria.add(e);
        }
        
        // 帳單業者 (放行的Group 要 等於  取消的 Group)
        if (null != group)
        {
            DetachedCriteria cancelUserCriteria = criteria.createCriteria("cancelUser");
            DetachedCriteria cancelGroupCriteria = cancelUserCriteria.createCriteria("group");
            
            // PK 有值，需加入為查詢條件
            if (null != group.getGroupPk())
            {
                cancelGroupCriteria.add(Restrictions.idEq(group.getGroupPk()));
            }

            // Group 其他查詢條件
            Example e = Example.create(group);
            e.enableLike(MatchMode.START);
            e.excludeZeroes();
            cancelGroupCriteria.add(e);
            
        }
        

        // 取消日期
        // 有起迄
        if (null != cancelDateFrom && null != cancelDateTo)
        {
            criteria.add(Restrictions.between("cancelDate",cancelDateFrom, cancelDateTo));
        }
        else if (null != cancelDateFrom) // 只有起
        {
            criteria.add(Restrictions.ge("cancelDate", cancelDateFrom));
        }
        else if (null != cancelDateTo) // 只有迄
        {
            criteria.add(Restrictions.le("cancelDate", cancelDateTo));
        }
        
        return criteria;
    }
    
    public void updateConfirm(ArrayList<Payment> payment,Boolean confirmStatus){
    	StringBuffer hql = new StringBuffer();
    	
    	hql.append("update PaymentCanceled set confirmStatus = :confirmStatus  ");
    	hql.append(",confirmUser = :confirmUser  ");
    	hql.append(",confirmDate = :sysdate  ");
        hql.append("where payment in (:payment) ");
        
        User user = UserUtil.getUser();

    	Query query = getSession().createQuery(hql.toString());
    	query.setParameter("confirmStatus", confirmStatus);
        query.setParameter("confirmUser", user );
        query.setParameter("sysdate", new Date());
        query.setParameterList("payment", payment);
        query.executeUpdate();
    }
}
